﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.IO;
using System.Security.Principal;
using System.ServiceModel;
using System.Text;
using System.Xml.Linq;
using System.Linq;
using org.nutilities.common;
using org.nutilities.utility;

namespace sample
{
  public class ItemProvider
  {
    private ServiceSettings _settings = null;
    
    public ItemProvider(NameValueCollection settings)
    {
      _settings = new ServiceSettings();
      _settings.AppendSettings(settings);

      Directory.SetCurrentDirectory(_settings["BaseDirectoryPath"]);

      if (ServiceSecurityContext.Current != null)
      {
        IIdentity identity = ServiceSecurityContext.Current.PrimaryIdentity;
        _settings["UserName"] = identity.Name;
      }
    }

    public VersionInfo GetVersion()
    {
      VersionInfo version = new VersionInfo();

      Type type = typeof(ItemProvider);
      version.Major = type.Assembly.GetName().Version.Major;
      version.Minor = type.Assembly.GetName().Version.Minor;
      version.Build = type.Assembly.GetName().Version.Build;
      version.Revision = type.Assembly.GetName().Version.Revision;

      return version;
    }

    public Response Initialize()
    {
      Response response = new Response();
      
      try
      { 
        string path = String.Format("{0}item-1.xml",
          _settings["XmlPath"]);


        Item item = new Item
        {
          Id = 1,
          StringValue = "Hello World!",
        };

        Utility.Write<Item>(item, path);

        string message = "Successfully initialized Item 1.";

        string url = String.Format("{0}items/1",
          _settings["BaseAddress"]);

        Status status = new Status
        {
          Identifier = "1",
          Level = StatusLevel.Success,
        };

        status.Messages.Add(message);

        Result result = new Result
        {
          Name = "uri",
          Value = url,
        };

        status.Results.Add(result);
        response.Append(status);
      }
      catch (Exception ex)
      {
        Status status = new Status
        {
          Identifier = "1",
          Level = StatusLevel.Error,
        };

        Utility.WriteException(ex, _settings["ErrorLogPath"]);

        string message = "Error while initializing Item 1. See server logs for more information.";

        status.Messages.Add(message);
        response.Append(status);
      }

      response.DateTimeStamp = DateTime.Now;
      return response;
    }

    public XElement GetItems()
    {
      XElement xElement = new XElement("items");

      try
      {
        string[] filePaths = Directory.GetFiles(_settings["XmlPath"], "*.xml");
        foreach (string path in filePaths)
        {
          if (File.Exists(path))
          {
           xElement.Add(Utility.ReadXml(path));
          }
        }
      }
      catch (Exception ex)
      {
        Response response = new Response();

        Status status = new Status
        {
          Level = StatusLevel.Error,
        };

        Utility.WriteException(ex, _settings["ErrorLogPath"]);

        string message = "Error while getting Items. See server logs for more information.";

        status.Messages.Add(message);
        response.DateTimeStamp = DateTime.Now;
        response.Append(status);

        xElement = XElement.Parse(Utility.SerializeDataContract<Response>(response));
      }

      return xElement;
    }

    public XElement GetRequestedItem(Request request)
    {
      XElement xElement = null;

      try
      {
        string id = request.RequestParameters.FirstOrDefault(p => p.Name == "id").Value;

        string path = String.Format("{0}item-{1}.xml",
          _settings["XmlPath"],
          id);

        if (File.Exists(path))
        {
          xElement = Utility.ReadXml(path);
        }
        else
        {
          Response response = new Response();

          Status status = new Status
          {
            Identifier = id.ToString(),
            Level = StatusLevel.Warning,
          };

          string message = String.Format("Item {0} was not found.", id);

          status.Messages.Add(message);
          response.DateTimeStamp = DateTime.Now;
          response.Append(status);

          xElement = XElement.Parse(Utility.SerializeDataContract<Response>(response));
        }
      }
      catch (Exception ex)
      {
        Response response = new Response();

        Status status = new Status
        {
          Level = StatusLevel.Error,
        };

        Utility.WriteException(ex, _settings["ErrorLogPath"]);

        string message = "Error while getting Items. See server logs for more information.";

        status.Messages.Add(message);
        response.DateTimeStamp = DateTime.Now;
        response.Append(status);

        xElement = XElement.Parse(Utility.SerializeDataContract<Response>(response));
      }

      return xElement;
    }

    public XElement GetItem(int id)
    {
      XElement xElement = null;

      try
      {
        string path = String.Format("{0}item-{1}.xml",
          _settings["XmlPath"],
          id);

        if (File.Exists(path))
        {
          xElement = Utility.ReadXml(path);
        }
        else
        {
          Response response = new Response();

          Status status = new Status
          {
            Identifier = id.ToString(),
            Level = StatusLevel.Warning,
          };

          string message = String.Format("Item {0} was not found.", id);

          status.Messages.Add(message);
          response.DateTimeStamp = DateTime.Now;
          response.Append(status);

          xElement = XElement.Parse(Utility.SerializeDataContract<Response>(response));
        }
      }
      catch (Exception ex)
      {
        Response response = new Response();

        Status status = new Status
        {
          Identifier = id.ToString(),
          Level = StatusLevel.Error,
        };

        Utility.WriteException(ex, _settings["ErrorLogPath"]);

        string message = String.Format("Error while getting Item {0}. See server logs for more information.",
                id);

        status.Messages.Add(message);
        response.DateTimeStamp = DateTime.Now;
        response.Append(status);

        xElement = XElement.Parse(Utility.SerializeDataContract<Response>(response));
      }

      return xElement;
    }

    public Response PostItem(Item sampleItem)
    {
      Response response = new Response();
      
      try
      { 
        string path = String.Format("{0}/item-{1}.xml",
          _settings["XmlPath"],
          sampleItem.Id);

        if (File.Exists(path))
        {
          Utility.Write<Item>(sampleItem, path);

          string message = String.Format("Successfully updated Item {0}.",
                sampleItem.Id.ToString());

          string url = String.Format("{0}items/{1}",
            _settings["BaseAddress"],
            sampleItem.Id.ToString());

          Status status = new Status
          {
            Identifier = sampleItem.Id.ToString(),
            Level = StatusLevel.Success,
          };

          status.Messages.Add(message);

          Result result = new Result
          {
            Name = "uri",
            Value = url,
          };

          status.Results.Add(result);
          response.Append(status);
        }
        else
        {
          Utility.Write<Item>(sampleItem, path);

          string message = String.Format("Successfully added Item {0}.",
                sampleItem.Id.ToString());

          string url = String.Format("{0}items/{1}",
            _settings["BaseAddress"],
            sampleItem.Id.ToString());

          Status status = new Status
          {
            Identifier = sampleItem.Id.ToString(),
            Level = StatusLevel.Success,
          };

          status.Messages.Add(message);

          Result result = new Result
          {
            Name = "uri",
            Value = url,
          };

          status.Results.Add(result);
          response.Append(status);
        }
      }
      catch (Exception ex)
      {
        Status status = new Status
        {
          Identifier = sampleItem.Id.ToString(),
          Level = StatusLevel.Error,
        };

        Utility.WriteException(ex, _settings["ErrorLogPath"]);

        string message = String.Format("Error while updating Item {0}. See server logs for more information.",
                sampleItem.Id.ToString());

        status.Messages.Add(message);
        response.Append(status);
      }

      response.DateTimeStamp = DateTime.Now;
      return response;
    }
  }
}